#include "AgentManager.h"

AgentManager::AgentManager()
{
}

AgentManager::~AgentManager()
{
}

AgentManager* AgentManager::m_xInstance = nullptr;

AgentManager* AgentManager::GetInstance()
{
	if (m_xInstance == nullptr)
	{
		m_xInstance = new AgentManager;
	}
	return m_xInstance;
}

void AgentManager::Destroy()
{
	if (m_xInstance != NULL)
	{
		delete m_xInstance;
		m_xInstance = NULL;
	}
}

void AgentManager::Initialize(std::vector<std::vector<Node*>> &pGrid)
{
	Grid = pGrid;

	m_iBunnies = 0;
	m_iWolves = 0;
	m_iBears = 0;
}

void AgentManager::AddAgent(Agent* pAgent)
{
	for (int i = 0; i < m_vAgents.size(); i++)
	{
		if (m_vAgents[i] == pAgent)
		{
			std::cout << "Error - Agent already exists in the vector" << std::endl;
			return;
		}
	}
	m_vAgents.push_back(pAgent);
}

void AgentManager::DeleteAgent(Agent* pAgent)
{
	for (unsigned int i = 0; i < m_vAgents.size(); i++)
	{
		if (m_vAgents[i] == pAgent)
		{
			m_vAgents[i]->Cleanup();
			delete m_vAgents[i];
			m_vAgents.erase(m_vAgents.begin() + i);
			return;
		}
	}
}

void AgentManager::Update(float pDeltaTime)
{
	for (unsigned int i = 0; i < m_vAgents.size(); i++)
	{
		if (m_vAgents[i]->ShouldKill())
		{
			DeleteAgent(m_vAgents[i]);
		}
		else
		{
			m_vAgents[i]->Update(pDeltaTime);
		}
	}
}

void AgentManager::SpawnAnimal(Animals pAnimal)
{
	int RandX = 0;
	int RandY = 0;
	
	bool foundEmpty = false;
	while (!foundEmpty)
	{
		RandX = rand() % 30;
		RandY = rand() % 30;

		if (Grid[RandX][RandY] != nullptr)
		{
			if (Grid[RandX][RandY]->m_bBlocked == false)
			{
				foundEmpty = true;
			}
		}
	}

	switch (pAnimal)
	{
		case Animals::Bunny:
			BunnyAgent* bAgent;
			bAgent = new BunnyAgent();
			bAgent->Initialize(Grid);

			bAgent->SetPosition(Grid[RandX][RandY]->m_vPosition);
			bAgent->SetCurrentNode(Grid[RandX][RandY]);

			AddAgent(bAgent);
			m_iBunnies++;
			break;
		case Animals::Wolf:
			WolfAgent* wAgent;
			wAgent = new WolfAgent();
			wAgent->Initialize(Grid);

			wAgent->SetPosition(Grid[RandX][RandY]->m_vPosition);
			wAgent->SetCurrentNode(Grid[RandX][RandY]);

			AddAgent(wAgent);
			m_iWolves++;
			break;
		case Animals::Bear:
			BearAgent* beAgent;
			beAgent = new BearAgent();
			beAgent->Initialize(Grid);

			beAgent->SetPosition(Grid[RandX][RandY]->m_vPosition);
			beAgent->SetCurrentNode(Grid[RandX][RandY]);

			AddAgent(beAgent);
			m_iBears++;
			break;
	}
}

void AgentManager::SpawnAnimal(Animals pAnimal, Node* pNode)
{
	switch (pAnimal)
	{
	case Animals::Bunny:
		BunnyAgent* bAgent;
		bAgent = new BunnyAgent();
		bAgent->Initialize(Grid);

		bAgent->SetPosition(pNode->m_vPosition);
		bAgent->SetCurrentNode(pNode);

		AddAgent(bAgent);
		break;
	case Animals::Wolf:
		WolfAgent* wAgent;
		wAgent = new WolfAgent();
		wAgent->Initialize(Grid);

		wAgent->SetPosition(pNode->m_vPosition);
		wAgent->SetCurrentNode(pNode);

		AddAgent(wAgent);
		break;
	case Animals::Bear:
		BearAgent* beAgent;
		beAgent = new BearAgent();
		beAgent->Initialize(Grid);

		beAgent->SetPosition(pNode->m_vPosition);
		beAgent->SetCurrentNode(pNode);

		AddAgent(beAgent);
		break;
	}
}

void AgentManager::Cleanup()
{
	for (unsigned int i = 0; i < m_vAgents.size(); i++)
	{
		m_vAgents[i]->Cleanup();
		delete m_vAgents[i];
		m_vAgents[i] = nullptr;
	}
	m_vAgents.clear();
}
